<template>
    <view :class="'interlayer '+(c||'')" :style="s">
        <block v-for="(n, i) in nodes" v-bind:key="i">
            <!--图片-->
            <view v-if="n.name=='img'" :class="'_img '+n.attrs.class" :style="n.attrs.style" :data-attrs="n.attrs" @tap.stop="imgtap">
                <rich-text v-if="ctrl[i]!=0" :nodes="[{attrs:{src:loading&&(ctrl[i]||0)<2?loading:(lazyLoad&&!ctrl[i]?placeholder:(ctrl[i]==3?errorImg:n.attrs.src||'')),alt:n.attrs.alt||'',width:n.attrs.width||'',style:'-webkit-touch-callout:none;max-width:100%;display:block'+(n.attrs.height?';height:'+n.attrs.height:'')},name:'img'}]" />
                <image class="_image" :src="lazyLoad&&!ctrl[i]?placeholder:n.attrs.src" :lazy-load="lazyLoad"
                 :show-menu-by-longpress="!n.attrs.ignore" :data-i="i" :data-index="n.attrs.i" data-source="img" @load="loadImg"
                 @error="error" />
            </view>
            <!--文本-->
            <text v-else-if="n.type=='text'" decode>{{n.text}}</text>
            <!--#ifndef MP-BAIDU-->
            <text v-else-if="n.name=='br'">\n</text>
            <!--#endif-->
            <!--视频-->
            <view v-else-if="((n.lazyLoad&&!n.attrs.autoplay)||(n.name=='video'&&!loadVideo))&&ctrl[i]==undefined" :id="n.attrs.id"
             :class="'_video '+(n.attrs.class||'')" :style="n.attrs.style" :data-i="i" @tap.stop="_loadVideo" />
            <video v-else-if="n.name=='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay||ctrl[i]==0"
             :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.attrs.source[ctrl[i]||0]"
             :unit-id="n.attrs['unit-id']" :data-id="n.attrs.id" :data-i="i" data-source="video" @error="error" @play="play" />
            <!--音频-->
            <audio v-else-if="n.name=='audio'" :ref="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author"
             :autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster"
             :src="n.attrs.source[ctrl[i]||0]" :data-i="i" :data-id="n.attrs.id" data-source="audio" @error.native="error"
             @play.native="play" />
            <!--链接-->
            <view v-else-if="n.name=='a'" :id="n.attrs.id" :class="'_a '+(n.attrs.class||'')" hover-class="_hover" :style="n.attrs.style"
             :data-attrs="n.attrs" @tap.stop="linkpress">
                <trees class="_span" c="_span" :nodes="n.children" />
            </view>
            <!--广告-->
            <!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :unit-id="n.attrs['unit-id']" :appid="n.attrs.appid" :apid="n.attrs.apid" :type="n.attrs.type" :adpid="n.attrs.adpid" data-source="ad" @error="error" />-->
            <!--列表-->
            <view v-else-if="n.name=='li'" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:flex;flex-direction:row'">
                <view v-if="n.type=='ol'" class="_ol-bef">{{n.num}}</view>
                <view v-else class="_ul-bef">
                    <view v-if="n.floor%3==0" class="_ul-p1">█</view>
                    <view v-else-if="n.floor%3==2" class="_ul-p2" />
                    <view v-else class="_ul-p1" style="border-radius:50%">█</view>
                </view>
                <trees class="_li" c="_li" :nodes="n.children" :lazyLoad="lazyLoad" :loading="loading" />
            </view>
            <!--表格-->
            <view v-else-if="n.name=='table'&&n.c&&n.flag" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:grid'">
                <trees v-for="(cell,n) in n.children" v-bind:key="n" :class="cell.attrs.class" :c="cell.attrs.class" :style="cell.attrs.style"
                 :s="cell.attrs.style" :nodes="cell.children" />
            </view>
            <view v-else-if="n.name=='table'&&n.c" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:table'">
                <view v-for="(tbody, o) in n.children" v-bind:key="o" :class="tbody.attrs.class" :style="(tbody.attrs.style||'')+(tbody.name[0]=='t'?';display:table-'+(tbody.name=='tr'?'row':'row-group'):'')">
                    <view v-for="(tr, p) in tbody.children" v-bind:key="p" :class="tr.attrs.class" :style="(tr.attrs.style||'')+(tr.name[0]=='t'?';display:table-'+(tr.name=='tr'?'row':'cell'):'')">
                        <trees v-if="tr.name=='td'" :nodes="tr.children" />
                        <trees v-else v-for="(td, q) in tr.children" v-bind:key="q" :class="td.attrs.class" :c="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')"
                         :s="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')" :nodes="td.children" />
                    </view>
                </view>
            </view>
            <!--#ifdef APP-PLUS-->
            <iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder"
             :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
            <embed v-else-if="n.name=='embed'" :style="n.attrs.style" :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
            <!--#endif-->
            <!--富文本-->
            <!--#ifdef MP-WEIXIN || MP-QQ || APP-PLUS-->
            <rich-text v-else-if="handler.use(n)" :id="n.attrs.id" :class="'_p __'+n.name" :nodes="[n]" />
            <!--#endif-->
            <!--#ifndef MP-WEIXIN || MP-QQ || APP-PLUS-->
            <rich-text v-else-if="!n.c" :id="n.attrs.id" :nodes="[n]" style="display:inline" />
            <!--#endif-->
            <trees v-else :class="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')" :c="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')"
             :style="n.attrs.style" :s="n.attrs.style" :nodes="n.children" :lazyLoad="lazyLoad" :loading="loading" />
        </block>
    </view>
</template>
<script module="handler" lang="wxs" src="./handler.wxs"></script>
<script>
    global.Parser = {};
    import trees from './trees'
    const errorImg = require('../libs/config.js').errorImg;
    export default {
        components: {
            trees
        },
        name: 'trees',
        data() {
            return {
                ctrl: [],
                placeholder: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="300" height="225"/>',
                errorImg,
                loadVideo: typeof plus == 'undefined',
                // #ifndef MP-ALIPAY
                c: '',
                s: ''
                // #endif
            }
        },
        props: {
            nodes: Array,
            lazyLoad: Boolean,
            loading: String,
            // #ifdef MP-ALIPAY
            c: String,
            s: String
            // #endif
        },
        mounted() {
            for (this.top = this.$parent; this.top.$options.name != 'parser'; this.top = this.top.$parent);
            this.init();
        },
        // #ifdef APP-PLUS
        beforeDestroy() {
            this.observer && this.observer.disconnect();
        },
        // #endif
        methods: {
            init() {
                for (var i = this.nodes.length, n; n = this.nodes[--i];) {
                    if (n.name == 'img') {
                        this.top.imgList.setItem(n.attrs.i, n.attrs['original-src'] || n.attrs.src);
                        // #ifdef APP-PLUS
                        if (this.lazyLoad && !this.observer) {
                            this.observer = uni.createIntersectionObserver(this).relativeToViewport({
                                top: 500,
                                bottom: 500
                            });
                            setTimeout(() => {
                                this.observer.observe('._img', res => {
                                    if (res.intersectionRatio) {
                                        for (var j = this.nodes.length; j--;)
                                            if (this.nodes[j].name == 'img')
                                                this.$set(this.ctrl, j, 1);
                                        this.observer.disconnect();
                                    }
                                })
                            }, 0)
                        }
                        // #endif
                    } else if (n.name == 'video' || n.name == 'audio') {
                        var ctx;
                        if (n.name == 'video') {
                            ctx = uni.createVideoContext(n.attrs.id
                                // #ifndef MP-BAIDU
                                , this
                                // #endif
                            );
                        } else if (this.$refs[n.attrs.id])
                            ctx = this.$refs[n.attrs.id][0];
                        if (ctx) {
                            ctx.id = n.attrs.id;
                            this.top.videoContexts.push(ctx);
                        }
                    }
                }
                // #ifdef APP-PLUS
                // APP 上避免 video 错位需要延时渲染
                setTimeout(() => {
                    this.loadVideo = true;
                }, 1000)
                // #endif
            },
            play(e) {
                var contexts = this.top.videoContexts;
                if (contexts.length > 1 && this.top.autopause)
                    for (var i = contexts.length; i--;)
                        if (contexts[i].id != e.currentTarget.dataset.id)
                            contexts[i].pause();
            },
            imgtap(e) {
                var attrs = e.currentTarget.dataset.attrs;
                if (!attrs.ignore) {
                    var preview = true,
                        data = {
                            id: e.target.id,
                            src: attrs.src,
                            ignore: () => preview = false
                        };
                    global.Parser.onImgtap && global.Parser.onImgtap(data);
                    this.top.$emit('imgtap', data);
                    if (preview) {
                        var urls = this.top.imgList,
                            current = urls[attrs.i] ? parseInt(attrs.i) : (urls = [attrs.src], 0);
                        uni.previewImage({
                            current,
                            urls
                        })
                    }
                }
            },
            loadImg(e) {
                var i = e.currentTarget.dataset.i;
                if (this.lazyLoad && !this.ctrl[i]) {
                    // #ifdef QUICKAPP-WEBVIEW
                    this.$set(this.ctrl, i, 0);
                    this.$nextTick(function() {
                        // #endif
                        // #ifndef APP-PLUS
                        this.$set(this.ctrl, i, 1);
                        // #endif
                        // #ifdef QUICKAPP-WEBVIEW
                    })
                    // #endif
                } else if (this.loading && this.ctrl[i] != 2) {
                    // #ifdef QUICKAPP-WEBVIEW
                    this.$set(this.ctrl, i, 0);
                    this.$nextTick(function() {
                        // #endif
                        this.$set(this.ctrl, i, 2);
                        // #ifdef QUICKAPP-WEBVIEW
                    })
                    // #endif
                }
            },
            linkpress(e) {
                var jump = true,
                    attrs = e.currentTarget.dataset.attrs;
                attrs.ignore = () => jump = false;
                global.Parser.onLinkpress && global.Parser.onLinkpress(attrs);
                this.top.$emit('linkpress', attrs);
                if (jump) {
                    // #ifdef MP
                    if (attrs['app-id']) {
                        return uni.navigateToMiniProgram({
                            appId: attrs['app-id'],
                            path: attrs.path
                        })
                    }
                    // #endif
                    if (attrs.href) {
                        if (attrs.href[0] == '#') {
                            if (this.top.useAnchor)
                                this.top.navigateTo({
                                    id: attrs.href.substring(1)
                                })
                        } else if (attrs.href.indexOf('http') == 0 || attrs.href.indexOf('//') == 0) {
                            // #ifdef APP-PLUS
                            plus.runtime.openWeb(attrs.href);
                            // #endif
                            // #ifndef APP-PLUS
                            uni.setClipboardData({
                                data: attrs.href,
                                success: () =>
                                    uni.showToast({
                                        title: '链接已复制'
                                    })
                            })
                            // #endif
                        } else
                            uni.navigateTo({
                                url: attrs.href,
                                fail() {
                                    uni.switchTab({
                                        url: attrs.href,
                                    })
                                }
                            })
                    }
                }
            },
            error(e) {
                var target = e.currentTarget,
                    source = target.dataset.source,
                    i = target.dataset.i;
                if (source == 'video' || source == 'audio') {
                    // 加载其他 source
                    var index = this.ctrl[i] ? this.ctrl[i].i + 1 : 1;
                    if (index < this.nodes[i].attrs.source.length)
                        this.$set(this.ctrl, i, index);
                    if (e.detail.__args__)
                        e.detail = e.detail.__args__[0];
                } else if (errorImg && source == 'img') {
                    this.top.imgList.setItem(target.dataset.index, errorImg);
                    this.$set(this.ctrl, i, 3);
                }
                this.top && this.top.$emit('error', {
                    source,
                    target,
                    errMsg: e.detail.errMsg
                });
            },
            _loadVideo(e) {
                this.$set(this.ctrl, e.target.dataset.i, 0);
            }
        }
    }
</script>

<style>
    /* 在这里引入自定义样式 */

    /* 链接和图片效果 */
    ._a {
        display: inline;
        padding: 1.5px 0 1.5px 0;
        color: #366092;
        word-break: break-all;
    }

    ._hover {
        text-decoration: underline;
        opacity: 0.7;
    }

    ._img {
        /* display: inline-block; */
    display: block;
        max-width: 100%;
        overflow: hidden;
    }

    /* #ifdef MP-WEIXIN */
    :host {
        display: inline;
    }

    /* #endif */

    /* #ifndef MP-ALIPAY || APP-PLUS */
    .interlayer {
        display: inherit;
        flex-direction: inherit;
        flex-wrap: inherit;
        align-content: inherit;
        align-items: inherit;
        justify-content: inherit;
        width: 100%;
        white-space: inherit;
    }

    /* #endif */

    ._b,
    ._strong {
        font-weight: bold;
    }

    /* #ifndef MP-ALIPAY */
    ._blockquote,
    ._div,
    ._p,
    ._ol,
    ._ul,
    ._li {
        display: block;
    }

    /* #endif */

    ._code {
        font-family: monospace;
    }

    ._del {
        text-decoration: line-through;
    }

    ._em,
    ._i {
        font-style: italic;
    }

    ._h1 {
        font-size: 2em;
    }

    ._h2 {
        font-size: 1.5em;
    }

    ._h3 {
        font-size: 1.17em;
    }

    ._h5 {
        font-size: 0.83em;
    }

    ._h6 {
        font-size: 0.67em;
    }

    ._h1,
    ._h2,
    ._h3,
    ._h4,
    ._h5,
    ._h6 {
        display: block;
        font-weight: bold;
    }

    ._image {
        display: block;
        width: 100%;
        height: 360px;
        margin-top: -360px;
        opacity: 0;
    }

    ._ins {
        text-decoration: underline;
    }

    ._li {
        flex: 1;
        width: 0;
    }

    ._ol-bef {
        width: 36px;
        margin-right: 5px;
        text-align: right;
    }

    ._ul-bef {
        display: block;
        margin: 0 12px 0 23px;
        line-height: normal;
    }

    ._ol-bef,
    ._ul-bef {
        flex: none;
        user-select: none;
    }

    ._ul-p1 {
        display: inline-block;
        width: 0.3em;
        height: 0.3em;
        overflow: hidden;
        line-height: 0.3em;
    }

    ._ul-p2 {
        display: inline-block;
        width: 0.23em;
        height: 0.23em;
        border: 0.05em solid black;
        border-radius: 50%;
    }

    ._q::before {
        content: '"';
    }

    ._q::after {
        content: '"';
    }

    ._sub {
        font-size: smaller;
        vertical-align: sub;
    }

    ._sup {
        font-size: smaller;
        vertical-align: super;
    }

    /* #ifdef MP-ALIPAY || APP-PLUS || QUICKAPP-WEBVIEW */
    ._abbr,
    ._b,
    ._code,
    ._del,
    ._em,
    ._i,
    ._ins,
    ._label,
    ._q,
    ._span,
    ._strong,
    ._sub,
    ._sup {
        display: inline;
    }

    /* #endif */

    /* #ifdef MP-WEIXIN || MP-QQ */
    .__bdo,
    .__bdi,
    .__ruby,
    .__rt {
        display: inline-block;
    }

    /* #endif */
    ._video {
        position: relative;
        display: inline-block;
        width: 300px;
        height: 225px;
        background-color: black;
    }

    ._video::after {
        position: absolute;
        top: 50%;
        left: 50%;
        margin: -15px 0 0 -15px;
        content: '';
        border-color: transparent transparent transparent white;
        border-style: solid;
        border-width: 15px 0 15px 30px;
    }
</style>
